﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XboxUserInterface.Variables;
using System.Collections;

namespace XboxUserInterface.Keys
{
    /// <summary>
    /// This class provides the structure and functions for handling which keys are associated with which controller elements.
    /// </summary>
    public class KeyMap
    {
        /// <summary>
        /// Name of the particular KeyMap
        /// </summary>
        private string name_;

        /// <summary>
        /// List of keys which contain the association data
        /// </summary>
        private List<Key> _keys;

        /// <summary>
        /// Boolean indicating whether the particualr KeyMap is active
        /// </summary>
        private bool _active;

        /// <summary>
        /// Default key mapping
        /// </summary>
        private static KeyMap _default = new KeyMap("Default Scheme")
        {
            Keys = 
            {
                new Key(KeyboardFunction.Mouse_Left,ControllerButtons.aButton),
                new Key(KeyboardFunction.Mouse_Right, ControllerButtons.bButton),
                new Key(KeyboardFunction.Mouse_Middle, ControllerButtons.xButton),
                new Key(KeyboardFunction.NoFunctions, ControllerButtons.yButton),
                new Key(KeyboardFunction.NoFunctions, ControllerButtons.backBtn),
                new Key(KeyboardFunction.NoFunctions, ControllerButtons.startBtn),
                new Key(KeyboardFunction.Browser_Back, ControllerButtons.leftTrigger),
                new Key(KeyboardFunction.Browser_Fwd, ControllerButtons.rightTrigger),
                new Key(KeyboardFunction.Volume_Down, ControllerButtons.leftButton),
                new Key(KeyboardFunction.Volume_Up, ControllerButtons.rightButton),
                new Key(KeyboardFunction.Mouse_Move, ControllerButtons.leftAnalog),
                new Key(KeyboardFunction.Mouse_Scroll, ControllerButtons.rightAnalog),
                new Key(KeyboardFunction.Media_PlayPause, ControllerButtons.dUp),
                new Key(KeyboardFunction.Media_Next, ControllerButtons.dRight),
                new Key(KeyboardFunction.Media_Stop, ControllerButtons.dDown),
                new Key(KeyboardFunction.Media_Prev, ControllerButtons.dLeft)
            },
        };


        /// <summary>
        /// Public reference to the default KeyMap
        /// </summary>
        public static KeyMap Default
        {
            get { return _default; }
        }
        
        /// <summary>
        /// The name of the Scheme
        /// </summary>
        public string SchemeName
        {
            get { return name_; }
            set { name_ = value; }
        }

        /// <summary>
        /// The list of Key associations
        /// </summary>
        public List<Key> Keys
        {
            get { return _keys; }
            set { _keys = value; }
        }

        /// <summary>
        /// Indicates whether the KeyMap is active
        /// </summary>
        public bool Active
        {
            get { return _active; }
            set { _active = value; }
        }

        /// <summary>
        /// Creates a new instance of KeyMap with the given name
        /// </summary>
        /// <param name="name">Name to give to the KeyMap</param>
        public KeyMap(string name)
        {
            name_ = name;
            _keys = new List<Key>();
            _active = false;
        }

        /// <summary>
        /// Converts the KeyMap to a string
        /// </summary>
        /// <returns>The name of the KeyMap</returns>
        public override string ToString()
        {
            return name_;
        }
    }

    /// <summary>
    /// Enumerable class to handle controller buttons - Depreciated
    /// </summary>
    public class Buttons : IEnumerable
    {
        private Key[] buttons_;

        public Key LeftTrigger
        {
            get { return buttons_[0]; }
            set { buttons_[0] = value; }
        }

        public Key RightTrigger
        {
            get { return buttons_[1]; }
            set { buttons_[1] = value; }
        }

        public Key LeftButton
        {
            get { return buttons_[2]; }
            set { buttons_[2] = value; }
        }

        public Key RightButton
        {
            get { return buttons_[3]; }
            set { buttons_[3] = value; }
        }

        public Key X
        {
            get { return buttons_[4]; }
            set { buttons_[4] = value; }
        }

        public Key Y
        {
            get { return buttons_[5]; }
            set { buttons_[5] = value; }
        }

        public Key A
        {
            get { return buttons_[6]; }
            set { buttons_[6] = value; }
        }

        public Key B
        {
            get { return buttons_[7]; }
            set { buttons_[7] = value; }
        }

        public Key Back
        {
            get { return buttons_[8]; }
            set { buttons_[8] = value; }
        }

        public Key Start
        {
            get { return buttons_[9]; }
            set { buttons_[9] = value; }
        }

        public Key LeftAnalog
        {
            get { return buttons_[10]; }
            set { buttons_[10] = value; }
        }

        public Key RightAnalog
        {
            get { return buttons_[11]; }
            set { buttons_[11] = value; }
        }

        public Key[] Button
        {
            get { return buttons_; }
            set { buttons_ = value; }
        }

        public Buttons()
        {
            buttons_ = new Key[12];
        }

        public IEnumerator GetEnumerator()
        {
            return buttons_.GetEnumerator();
        }
    }

    /// <summary>
    /// Enumerable class to handle controller analog sticks - Depreciated
    /// </summary>
    public class AnalogSticks : IEnumerable
    {
        private Key[] analogs_;

        public Key LeftAnalog
        {
            get { return analogs_[0]; }
            set { analogs_[0] = value; }
        }

        public Key RightAnalog
        {
            get { return analogs_[1]; }
            set { analogs_[1] = value; }
        }

        public Key[] Buttons
        {
            get { return analogs_; }
            set { analogs_ = value; }
        }

        public AnalogSticks()
        {
            analogs_ = new Key[2];
        }

        public IEnumerator GetEnumerator()
        {
            return analogs_.GetEnumerator();
        }
    }

    /// <summary>
    /// Enumerable class to handle controller D-Pad - Depreciated
    /// </summary>
    public class DPad : IEnumerable
    {
        private Key[] DPad_;

        public Key Up
        {
            get { return DPad_[0]; }
            set { DPad_[0] = value; }
        }

        public Key Down
        {
            get { return DPad_[1]; }
            set { DPad_[1] = value; }
        }

        public Key Left
        {
            get { return DPad_[2]; }
            set { DPad_[2] = value; }
        }

        public Key Right
        {
            get { return DPad_[3]; }
            set { DPad_[3] = value; }
        }

        public Key[] Buttons
        {
            get { return DPad_; }
            set { DPad_ = value; }
        }

        public DPad()
        {
            DPad_ = new Key[4];
        }

        public IEnumerator GetEnumerator()
        {
            return DPad_.GetEnumerator();
        }
    }

    /// <summary>
    /// Class which contains data for button association
    /// </summary>
    public class Key
    {
        /// <summary>
        /// KeyboardFunction associated with given button / key
        /// </summary>
        private KeyboardFunction keyCode_;

        /// <summary>
        /// Controller button to associate with KeyboardFunction
        /// </summary>
        private ControllerButtons _button;

        /// <summary>
        /// The KeyboardFunction associated with a Key
        /// </summary>
        public KeyboardFunction KeyCode
        {
            get { return keyCode_; }
            set { keyCode_ = value; }
        }

        /// <summary>
        /// The controller feature associated with a Key
        /// </summary>
        public ControllerButtons GamePadKey
        {
            get { return _button;}
            set { _button = value;}
        }

        /// <summary>
        /// Creates a new instance of Key and associates the given KeyboardFunction with the given controller feature.
        /// </summary>
        /// <param name="keyCode">Keyboard function to associate with controller feature</param>
        /// <param name="gamePadKey">Controller feature to reference</param>
        public Key(KeyboardFunction keyCode, ControllerButtons gamePadKey)
        {
            keyCode_ = keyCode;
            _button = gamePadKey;
        }

        /// <summary>
        /// Creates a new instance of Key and associates it with two null operators
        /// </summary>
        public Key()
        {
            keyCode_ = KeyboardFunction.NoFunctions;
            _button = ControllerButtons.nullKey;
        }

        /// <summary>
        /// Represents the Key as a string
        /// </summary>
        /// <returns>The virtual keycode associated with the Key</returns>
        public override string ToString()
        {
            return KeyCode.ToString();
        }
    }
}
